package com.dazzle.core.web.filter.security;

import java.io.IOException;
import java.util.Collection;

import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {
	//与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应，
	//其他的两个组件，已经在AbstractSecurityInterceptor定义
	private MySecurityMetadataSource securityMetadataSource;
	
	
	public MySecurityMetadataSource getSecurityMetadataSource() {
		return securityMetadataSource;
	}

	public void setSecurityMetadataSource(MySecurityMetadataSource securityMetadataSource) {
		this.securityMetadataSource = securityMetadataSource;
	}

	@Override
	public SecurityMetadataSource obtainSecurityMetadataSource() {
		return this.securityMetadataSource;
	}
	
	@Resource
	private MyAccessDecisionManager  myAccessDecisionManager;
	
	
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		FilterInvocation fi = new FilterInvocation(request, response, chain);
		invoke(fi);
	}
	
	private void invoke(FilterInvocation fi) throws IOException, ServletException {
		// object为FilterInvocation对象
		//1.获取请求资源的权限
		//执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);
		//2.是否拥有权限
		//获取安全主体，可以强制转换为UserDetails的实例
		//1) UserDetails
		//Authentication authenticated = authenticateIfRequired();
		//this.accessDecisionManager.decide(authenticated, object, attributes);
		//用户拥有的权限
		//2) GrantedAuthority
		//Collection<GrantedAuthority> authenticated.getAuthorities()
		System.out.println("用户发送请求！ ");
		
		Authentication authenticated = SecurityContextHolder.getContext().getAuthentication();
		if(StringUtils.isNotEmpty(authenticated.getName()) && !"anonymousUser".equals(authenticated.getName())){
			
			System.out.println(authenticated.getName());
			System.out.println("--进行权限判断--");
			//返回所请求资源所需要的权限
//			if(!"admin".equals(authenticated.getName()) && !"/home.do".equals(fi.getRequestUrl())){//假如是管理员,则有全部权限
				Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(fi);
				this.myAccessDecisionManager.decide(authenticated, fi, attributes);
//			}
			//throw new AccessDeniedException("Access is denied! Url:" + fi.getRequestUrl() + " User:" + authenticated.getName());
		}else{
			System.out.println("--用户未登录--");
			throw new AccessDeniedException("login first!");
			//fi.getResponse().sendRedirect("/jsp.do?view=login");
		}
		
		InterceptorStatusToken token = null;
		token = super.beforeInvocation(fi);
		
		try {
			fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
		} finally {
			super.afterInvocation(token, null);
		}
	}

//	public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
//		return securityMetadataSource;
//	}
//
//	public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
//		this.securityMetadataSource = securityMetadataSource;
//	}
	
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
	}
	
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Class<? extends Object> getSecureObjectClass() {
		//下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
		return FilterInvocation.class;
	}
}
